package com.sirap.spring.boot.demo.controller;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Lists;
import com.sirap.basic.component.Konstants;
import com.sirap.basic.domain.MexTextLine;
import com.sirap.basic.exception.MexException;
import com.sirap.basic.tool.D;
import com.sirap.basic.util.Amaps;
import com.sirap.basic.util.DateUtil;
import com.sirap.basic.util.FileUtil;
import com.sirap.basic.util.IOUtil;
import com.sirap.basic.util.ObjectUtil;
import com.sirap.basic.util.RandomUtil;
import com.sirap.basic.util.StrUtil;
import com.sirap.basic.util.XCodeUtil;
import com.sirap.common.domain.Album;
import com.sirap.extractor.FishCache;
import com.sirap.extractor.TagsCache;
import com.sirap.fish.fetchers.CatImageFetchers;
import com.sirap.spring.boot.demo.config.FishKonfig;

public abstract class BaseController {

	public String KEY_USER = "user";
	public String SUPER_USER = "ninja";
	public int PAGE_SIZE_TEN = 10;
	
	public String redirect(String target) {
    	return "redirect:" + target;
	}

	public String charsetX() {
		String temp = Konstants.CODE_UTF8 + " " + Konstants.CODE_GBK;
		String desire = temp.replace(charset(), "").trim();
		return desire;
	}

	public String charset() {
		return Charset.defaultCharset().name();
	}
	
	public String ts() {
		return DateUtil.timestamp();
	}
	
	public String storage() {
		String pathname = FishKonfig.storage();
		FileUtil.makeDirectories(pathname);
		
		return pathname;
	}
	
	public String pathOfUpload() {
		return StrUtil.useSeparator(storage(), "albums", "upload");
	}
	
	public String pathOfBible() {
		return StrUtil.useSeparator(storage(), "bible");
	}

	public String pathOfAlbums() {
		return StrUtil.useSeparator(storage(), "albums");
	}
	
	public HttpSession session(HttpServletRequest request) {
		return request.getSession();
	}
	
	public String save(MultipartFile file, String filepath) {
		byte[] bytes = null;

		try {
			bytes = file.getBytes();
			IOUtil.save(bytes, filepath);
		} catch (IOException ex) {
			ex.printStackTrace();
			throw new MexException(ex);
		}

		return filepath;
	}

	public void readIntoStream(OutputStream os, String filepath) throws Exception {
		byte[] bytes = new byte[1024];
		try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filepath));) {
			int i = bis.read(bytes);
			while (i != -1) {
				os.write(bytes, 0, bytes.length);
				os.flush();
				i = bis.read(bytes);
			}
		}
	}
	
	public List<String> fakeFilenames() {
        List<String> items = Lists.newArrayList();
        for(int i = 0; i < 30; i++) {
        	items.add(storage() + "_" + RandomUtil.digits(18));
        }
        return items;
    }
	
	public List<List<Object>> fakeResult(int numberOfLines) {
		List<List<Object>> lines = Lists.newArrayList();
		for(int i = 1; i <= numberOfLines; i++) {
			List<Object> items = Lists.newArrayList();
			items.add("Row: " + i);
			items.add(RandomUtil.alphanumeric(8));
			items.add(RandomUtil.letters(8));
			items.add(RandomUtil.digits(8));
			lines.add(items);
		}	
		
		return lines;
	}
	
	public List<Map<String, Object>> readCatTagsFromCacheOrFile(String filepath) {
		String location = StrUtil.useSeparator(storage(), filepath);
    	Long lastmodify = FileUtil.getIfNormalFile(location).lastModified();
    	List<Map<String, Object>> tags = null;
    	Long current = TagsCache.getLastmodified(location);
    	D.pla(location, current, lastmodify);
    	if(current == null || !current.equals(lastmodify)) {
    		List<String> lines = IOUtil.readLinesWithUTF8(location);
    		tags = CatImageFetchers.tagsFromList(lines);
    		TagsCache.putLines(location, tags);
    		TagsCache.putLastmodified(location, lastmodify);
    		D.pl("WordsCache miss");
    	} else {
    		tags = TagsCache.getLines(location);
    		D.pl("WordsCache hit");
    	}
    	
    	return tags;
	}
	
	public Album readAlbumFromCacheOrFetcher(String albumurl, Class<?> clazz) {
		D.at();
		D.pl(albumurl);
    	Album photos = FishCache.get(albumurl);
    	if(photos != null) {
    		D.pl("cache hit");
    	} else {
    		if(clazz == null) {
    			return null;
    		}
    		D.pl("cache miss, using class: {0}.getAlbum" + clazz.getName());
    		Class[] arr = {String.class};
    		photos = (Album)ObjectUtil.execute(clazz, "getAlbum", arr, albumurl);
    		D.pla(albumurl, photos.getLinks().size());
    		FishCache.put(albumurl, photos);
    	}

    	return photos;
	}
	
	public Map<String, Object> getAlbumDetail(String base64url, Class<?> clazz) {
		D.at();
    	String niceurl = XCodeUtil.fromBase64(base64url);
    	D.pla(base64url, niceurl);
		
    	Map<String, Object> map = Amaps.newTreeMap();
    	Album bum = readAlbumFromCacheOrFetcher(niceurl, clazz);
		map.put("title", bum.getName());
		map.put("list", bum.getListObj());
		map.put("niceurl", bum.getUrl());
		map.put("when", bum.getWhen());
		map.put("timeago", bum.getTimeAgo());
    	D.pjsp(map);
	
		return map;
	}
	
	public boolean isSuperUser(HttpServletRequest request) {
		return false;
	}
	
	public String byHtmlBR(List lines) {
		StringBuffer sb = new StringBuffer();
		boolean theFirstOne = true;
		for(Object obj : lines) {
			if(!theFirstOne) {
				sb.append("<BR>");
			}
			if(obj instanceof MexTextLine) {
				MexTextLine line = (MexTextLine)obj;
				sb.append(line.getObj());
			} else {
				sb.append(obj);
			}
			theFirstOne = false;
		}
		return sb.toString();
	}
}
